package org.zls.client;

import org.zls.client.service.ServerService;

import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.gwtext.client.data.ArrayReader;
import com.gwtext.client.data.FieldDef;
import com.gwtext.client.data.IntegerFieldDef;
import com.gwtext.client.data.MemoryProxy;
import com.gwtext.client.data.Record;
import com.gwtext.client.data.RecordDef;
import com.gwtext.client.data.Store;
import com.gwtext.client.data.StringFieldDef;
import com.gwtext.client.widgets.grid.BaseColumnConfig;
import com.gwtext.client.widgets.grid.CheckboxColumnConfig;
import com.gwtext.client.widgets.grid.CheckboxSelectionModel;
import com.gwtext.client.widgets.grid.ColumnConfig;
import com.gwtext.client.widgets.grid.ColumnModel;
import com.gwtext.client.widgets.grid.GridPanel;
import com.gwtext.client.widgets.grid.RowSelectionModel;
import com.gwtext.client.widgets.grid.event.RowSelectionListener;

public class ResultTable extends GridPanel {

	private String[] cols;
	private String[][] data;
	private ArrayReader reader;

	final CheckboxSelectionModel sm = new CheckboxSelectionModel();

	private BaseColumnConfig[] columns = new BaseColumnConfig[] {
			new CheckboxColumnConfig(sm),
			new ColumnConfig("Title", "title", 100, true, null, "title"),
			new ColumnConfig("Name", "name", 100, true, null, "name"),
			new ColumnConfig("Department", "department", 100, true, null,
					"department"),
			new ColumnConfig("Catalog", "catalog", 50, true, null, "catalog"),
			new ColumnConfig("Term", "term", 50, true, null, "term"),
			new ColumnConfig("Professor", "professor", 50, true, null,
					"professor"),
			new ColumnConfig("Meetings", "meetings", 50, true, null, "meetings"),
			new ColumnConfig("Size", "size", 50, true, null, "size"),
			new ColumnConfig("Primarily for", "primarily", 50, true, null,
					"primarily"),
			new ColumnConfig("Q Overall", "q_overall", 50, true, null,
					"q_overall"),
			new ColumnConfig("Q Professor", "q_professor", 50, true, null,
					"q_professor"),
			new ColumnConfig("Q Readings", "q_readings", 50, true, null,
					"q_readings"),
			new ColumnConfig("Q Workload", "q_workload", 50, true, null,
					"q_workload"),
			new ColumnConfig("Q Difficulty", "q_difficulty", 50, true, null,
					"q_difficulty") };

	private RecordDef recordDef = new RecordDef(new FieldDef[] {
			new StringFieldDef("title"), new StringFieldDef("name"),
			new StringFieldDef("department"), new IntegerFieldDef("catalog"),
			new StringFieldDef("term"), new StringFieldDef("professor"),
			new StringFieldDef("meetings"), new IntegerFieldDef("size"),
			new StringFieldDef("primarily"), new StringFieldDef("q_overall"),
			new StringFieldDef("q_professor"),
			new StringFieldDef("q_readings"), new StringFieldDef("q_workload"),
			new StringFieldDef("q_difficulty") });

	public ResultTable() {
		data = new String[0][0];

		reader = new ArrayReader(recordDef);

		MemoryProxy proxy = new MemoryProxy(data);

		Store store = new Store(proxy, reader);
		store.load();
		setStore(store);

		sm.addListener(new RowSelectionListener() {

			public boolean doBeforeRowSelect(RowSelectionModel sm,
					int rowIndex, boolean keepExisting, Record record) {

				return keepExisting ? true : false;
			}

			public void onRowDeselect(RowSelectionModel sm, int rowIndex,
					Record record) {
				// TODO Auto-generated method stub
			}

			public void onRowSelect(RowSelectionModel sm, int rowIndex,
					Record record) {

			}

			public void onSelectionChange(RowSelectionModel sm) {
				// TODO Auto-generated method stub

			}

		});

		setSelectionModel(sm);
		setColumnModel(getColumnConfigs());
		setAutoHeight(true);
		setEnableHdMenu(false);
		setEnableColumnResize(true);
		setMinColumnWidth(50);
		this.getView().setForceFit(true);
		setTrackMouseOver(true);
		 setDisableSelection(true);
		// this.getView().setEnableRowBody(true);
		// this.getView().setAutoFill(true);
		// this.getView().fitColumns(true);
		// setFrame(true);

		/*
		 * TODO: Doesn't do anything. Hacked in the tabs that use this. Will
		 * have to investigate the JavaScript
		 */
		
		// setMonitorWindowResize(true);
		setLoadMask("Loading...");
		setAutoExpandColumn("name");

		hideColumn("department");
		hideColumn("catalog");
		hideColumn("length");
		hideColumn("size");
		hideColumn("primarily");
		hideColumn("q_professor");
		hideColumn("q_readings");
		hideColumn("q_workload");
		hideColumn("q_difficulty");

		cols = new String[recordDef.getFields().length];

		for (int i = 0; i < cols.length; i++) {
			cols[i] = recordDef.getFields()[i].getName();
		}
	}

	public void refresh() {
		getStore().removeAll();
		getStore().commitChanges();
		Window.alert("Whatup, bitches");
	}

	public void update(String query) {

		// TODO: We should probably get only data for columns shown.
		ServerService.Util.getInstance().getTableData(query, cols,
				new AsyncCallback<String[][]>() {

					public void onFailure(Throwable caught) {
						Window
								.alert("ERROR: Asynchronous Call failed from ResultTable.update().");
					}

					public void onSuccess(String[][] result) {
						data = result;
						MemoryProxy proxy = new MemoryProxy(data);
						Store store = new Store(proxy, reader);
						store.load();
						reconfigure(store, getColumnModel());
					}
				});
	}

	protected ColumnModel getColumnConfigs() {
		ColumnModel columnModel = null;
		if (columns == null) {
			columnModel = new ColumnModel(columns);
		} else {
			BaseColumnConfig[] columnConfigs = new BaseColumnConfig[columns.length];
			for (int i = 0; i < columns.length; i++) {
				columnConfigs[i] = columns[i];
			}
			columnModel = new ColumnModel(columnConfigs);
		}
		return columnModel;
	}

	public BaseColumnConfig[] getColumns() {
		return columns;
	}
}